package org.drl.tvkit.error;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;

import org.drl.tvkit.BuildConfig;

/**
 * Darry Ring
 * 拦截全局的系统异常，并进行处理
 */
public class GlobalCrashHandler implements Thread.UncaughtExceptionHandler {
	private static String ERROR_LOG_PATH;
	final static String ERROR_LOG_UPLOAD_URL = "";

	public GlobalCrashHandler() {
		super();
	}

	@Override
	public void uncaughtException(Thread thread, Throwable throwable) {
		throwable.printStackTrace();
		if (!isStrageException(thread, throwable)) {
			saveErrorLog(thread, throwable);
			if (!BuildConfig.DEBUG) {
				uploadErrorLog(thread, throwable);
			}
		}

		if (throwable instanceof IndexOutOfBoundsException) {

		} else if (throwable instanceof NullPointerException) {

		}
		android.os.Process.killProcess(android.os.Process.myPid());
	}

	/**
	 * 创维盒子开机首次启动的时候，会报该异常
	 * 
	 * @param throwable
	 * @return
	 */
	private boolean isStrageException(Thread thread, Throwable throwable) {
		boolean b1 = (thread != null && thread.getId() == 1
				&& throwable != null && throwable.toString() != null && throwable
				.toString()
				.startsWith(
						"java.lang.RuntimeException: Unable to destroy activity")
		// && throwable.toString().endsWith("java.lang.NullPointerException")
		);
		boolean b2 = (thread != null && thread.getId() == 1
				&& throwable != null && throwable.toString() != null && throwable
				.toString()
				.startsWith(
						"java.lang.IllegalStateException: Activity has been destroyed"));
		return b1 || b2;
	}

	/*
	 * TODO 上传错误日志。暂无错误日志接口。
	 */
	private void uploadErrorLog(Thread thread, Throwable throwable) {
		@SuppressWarnings("unused")
		String errlog = getErrorLog(thread, throwable);
	}

	private void saveErrorLog(Thread thread, Throwable throwable) {
		String errLog = getErrorLog(thread, throwable);

		File logFile = new File(ERROR_LOG_PATH, "error.log");
		OutputStream os = null;
		try {
			os = new FileOutputStream(logFile, true);
			os.write(errLog.getBytes("utf-8"));
			os.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	/**
	 * @param e
	 * @return
	 */
	public final static String exceptionToString(Exception e) {
		try {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			return "\r\n" + sw.toString() + "\r\n";
		} catch (Exception e2) {
			return "";
		}
	}

	/**
	 * @param e
	 * @return
	 */
	public final static String exceptionToString(Throwable throwable) {
		try {
			StringWriter sw = new StringWriter();
			StackTraceElement[] stackTraces = throwable.getStackTrace();
			for (StackTraceElement stackTraceElement : stackTraces) {
				sw.append("\t" + stackTraceElement.toString() + "\n");
			}
			return "\r\n" + sw.toString() + "\r\n";
		} catch (Exception e2) {
			return "";
		}
	}

	@SuppressWarnings("deprecation")
	private String getErrorLog(Thread thread, Throwable throwable) {
		String errLog = null;

		StringBuffer errContentMsg = new StringBuffer();
		StackTraceElement[] stackTraces = throwable.getStackTrace();
		for (StackTraceElement stackTraceElement : stackTraces) {
			errContentMsg.append("\t" + stackTraceElement.toString() + "\n");
		}

		String time = new Date(System.currentTimeMillis()).toLocaleString();
		String errThreadMsg = "Uncaught Exception in thread ===>"
				+ thread.getName();
		String errSummaryMsg = "Uncaught Exception cause by ===>"
				+ throwable.toString();
		errLog = time
				+ "\n"
				+ errThreadMsg
				+ "\n"
				+ errSummaryMsg
				+ "\n"
				+ errContentMsg.toString()
				+ ">>>>=================================================================================================<<<<\n\n";

		return errLog;
	}

}
